#pragma once
#include "ncti_base.h"
#include <NctiPosition.h>
#include "NctiMeshBody.h"

namespace NCTI
{
    class DECL_NCTI_BASE NctiBaseInlinePub {
    public:

        Ncti_Integer ElementDim(int tp);

        Ncti_Integer ElementOrder(int tp);

        Ncti_Integer ElementFace(int tp);

        Ncti_Integer ElementEdge(int tp);

        Ncti_Integer ElementVert(int tp);
    };

    class NctiDisplayModelBody;

    /**
    * @brief mesh manager
    */
    class DECL_NCTI_BASE NctiMeshManerger
    {
    public:
        static NctiMeshManerger& Instance();
        ~NctiMeshManerger();

        /**
       * @brief clear all mesh
       */
        void Clear();

        /**
       * @brief Add Mesh Data to manager,internal calculate the number
       * @details used in NctiDisplayGridMesh for display.
       * @param[in] i_body, the mesh body
       * @param[in] o_startNode,first node number
       * @param[in] o_startElem,first element number
       * @see NctiDisplayGridMesh
       */
        bool AddMeshData(NctiMeshBody*i_body, Ncti_UInteger&o_startNode, Ncti_UInteger& o_startElem);

        /**
       * @brief Set Mesh Data to manager,set the number
       * @details used in NctiDisplayGridMesh for load file.
       * @param[in] i_body, the mesh body
       * @param[in] i_startNode,first node number
       * @param[in] i_startElem,first element number
       * @see NctiDisplayGridMesh
       */
        bool SetMeshData(NctiMeshBody* i_body, Ncti_UInteger i_startNode, Ncti_UInteger i_startElem);

        /**
       * @brief Remove Mesh Data to manager
       * @details used in NctiDisplayGridMesh for deconstruction
       * @param[in] i_body, the mesh body
       * @see NctiDisplayGridMesh
       */
        void RemoveMeshData(NctiMeshBody* i_body);

        /**
       * @brief Find mesh body form model body
       * @param[in] model, the model display object associate with the mesh body
       * @see NctiDisplaySetGeometry
       */
        NctiMeshBody* FindBodyFromModel(NctiDisplayModelBody* model)const;

        /**
       * @brief Find mesh body form node number
       * @param[in] e_nid, node number
       * @see NctiMeshBody
       */
        NctiMeshBody* FindBodyFromVertex(Ncti_UInteger e_nid)const;

        /**
       * @brief Find mesh body form element number
       * @param[in] e_cid, element number
       * @see NctiMeshBody
       */
        NctiMeshBody* FindBodyFromElement(Ncti_UInteger e_cid)const;

        /**
        * @brief all vertex count
        */
        bool AllVertexCount()const;

        /**
       * @brief get node position from node number
       * @param[in] i_nid, node number
       * @see NctiPosition
       */
        NctiPosition GetVertex(Ncti_UInteger i_nid)const;

        /**
        * @brief all vertex count
        */
        bool AllElementCount()const;

        /**
       * @brief get node position from element number
       * @param[in] i_cid, element number
       * @return NctiMeshElement
       */
        NctiMeshElement GetElement(Ncti_UInteger i_cid)const;
        
    private:
        NctiMeshManerger();
        struct PrivateData;
        PrivateData* _d;
    };
};

